<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>chunk_analyzer 模块评估报告 - 7f486e</title>
  <style>
    body { font-family: Arial, sans-serif; line-height: 1.6; margin: 0; padding: 20px; color: #333; }
    h1, h2, h3 { color: #2c3e50; }
    .container { max-width: 1200px; margin: 0 auto; }
    .card { background: #fff; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); margin-bottom: 20px; padding: 20px; }
    .success { color: #27ae60; }
    .error { color: #e74c3c; }
    .info { color: #3498db; }
    table { width: 100%; border-collapse: collapse; margin: 10px 0; }
    th, td { text-align: left; padding: 12px; border-bottom: 1px solid #eee; }
    th { background-color: #f8f9fa; }
    tr:hover { background-color: #f5f5f5; }
    pre { background: #f8f9fa; padding: 15px; border-radius: 5px; overflow-x: auto; }
    .progress-container { width: 100%; background-color: #f1f1f1; border-radius: 5px; }
    .progress-bar { height: 20px; border-radius: 5px; }
    .success-bg { background-color: #4CAF50; }
    .pending-bg { background-color: #2196F3; }
    .error-bg { background-color: #f44336; }
    .tag { display: inline-block; padding: 3px 8px; border-radius: 3px; font-size: 12px; font-weight: bold; }
    .tag-success { background-color: #e8f5e9; color: #2e7d32; }
    .tag-error { background-color: #ffebee; color: #c62828; }
    .tag-pending { background-color: #e3f2fd; color: #1565c0; }
  </style>
</head>
<body>
  <div class="container">
    <h1>chunk_analyzer 模块评估报告</h1>
    
    <div class="card">
      <h2>基本信息</h2>
      <table>
        <tr>
          <td width="150"><strong>模块名称</strong></td>
          <td>chunk_analyzer</td>
        </tr>
        <tr>
          <td><strong>模块类型</strong></td>
          <td>ModuleType.CHUNK_ANALYZER</td>
        </tr>
        <tr>
          <td><strong>提交SHA</strong></td>
          <td>7f486ea6eebf0afce74f2e59763b9b82b78629dc.patch</td>
        </tr>
        <tr>
          <td><strong>目标版本</strong></td>
          <td>4.0.11</td>
        </tr>
        <tr>
          <td><strong>执行时间</strong></td>
          <td>2025-05-15T01:42:09.313446</td>
        </tr>
        <tr>
          <td><strong>状态</strong></td>
          <td>
            <span class="tag tag-success">成功</span>
          </td>
        </tr>
      </table>
    </div>
    
    <div class="card">
      <h2>输入信息</h2>
      <table>
        
                <tr>
                  <td width="200"><strong>原始补丁路径</strong></td>
                  <td>/home/elpsy/workspace/sow/patch-backport/workspace/redis/redis/7f486e/patches/upstream_7f486e.patch</td>
                </tr>
                
                <tr>
                  <td width="200"><strong>代码仓库路径</strong></td>
                  <td>../backport-test/redis</td>
                </tr>
                
      </table>
    </div>
    
    <div class="card">
      <h2>输出信息</h2>
      <table>
        
                <tr>
                  <td width="200"><strong>状态</strong></td>
                  <td>成功</td>
                </tr>
                
                <tr>
                  <td width="200"><strong>成功次数</strong></td>
                  <td>1</td>
                </tr>
                
                <tr>
                  <td width="200"><strong>总尝试次数</strong></td>
                  <td>1</td>
                </tr>
                
                <tr>
                  <td width="200"><strong>执行时间</strong></td>
                  <td>0.028412</td>
                </tr>
                
                <tr>
                  <td width="200"><strong>总块数</strong></td>
                  <td>3</td>
                </tr>
                
                <tr>
                  <td width="200"><strong>成功应用块数</strong></td>
                  <td>0</td>
                </tr>
                
                <tr>
                  <td width="200"><strong>成功率</strong></td>
                  <td>0.00%</td>
                </tr>
                
                <tr>
                  <td width="200"><strong>剩余补丁路径</strong></td>
                  <td>/home/elpsy/workspace/sow/patch-backport/workspace/redis/redis/7f486e/chunk_patches/remaining_chunks_20250515_014209.patch</td>
                </tr>
                
      </table>
    </div>
    
    
        <div class="card">
          <h2>补丁块应用统计</h2>
          
          <div class="progress-container">
            <div class="progress-bar success-bg" style="width: 0%"></div>
          </div>
          <p>
            成功应用 <strong class="success">0</strong> 个块，
            总共 <strong>3</strong> 个块
            (成功率: <strong>0.0%</strong>)
          </p>
        </div>
        
        <div class="card">
          <h2>补丁内容详情</h2>
          <div class="tabs">
            <div class="tab-header">
              <button class="tab-button active" onclick="openTab(event, 'original-patch')">原始补丁</button>
              <button class="tab-button" onclick="openTab(event, 'applied-patches')">应用成功的补丁</button>
              <button class="tab-button" onclick="openTab(event, 'remaining-patch')">未应用成功的补丁</button>
            </div>
            
            <div id="original-patch" class="tab-content" style="display:block;">
              <h3>原始补丁内容</h3>
              <div class="code-container">
                <pre class="code-block">From 7f486ea6eebf0afce74f2e59763b9b82b78629dc Mon Sep 17 00:00:00 2001
From: Yossi Gottlieb &lt;yossigo@gmail.com&gt;
Date: Wed, 11 Oct 2023 22:45:34 +0300
Subject: [PATCH] Fix issue of listen before chmod on Unix sockets
 (CVE-2023-45145)

Before this commit, Unix socket setup performed chmod(2) on the socket
file after calling listen(2). Depending on what umask is used, this
could leave the file with the wrong permissions for a short period of
time. As a result, another process could exploit this race condition and
establish a connection that would otherwise not be possible.

We now make sure the socket permissions are set up prior to calling
listen(2).

(cherry picked from commit a11b3bc34a054818f2ac70e50adfc542ca1cba42)
---
 src/anet.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/anet.c b/src/anet.c
index 4ea201df57f..10840fca20d 100644
--- a/src/anet.c
+++ b/src/anet.c
@@ -407,13 +407,16 @@ int anetUnixGenericConnect(char *err, const char *path, int flags)
     return s;
 }
 
-static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog) {
+static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog, mode_t perm) {
     if (bind(s,sa,len) == -1) {
         anetSetError(err, "bind: %s", strerror(errno));
         close(s);
         return ANET_ERR;
     }
 
+    if (sa-&gt;sa_family == AF_LOCAL && perm)
+        chmod(((struct sockaddr_un *) sa)-&gt;sun_path, perm);
+
     if (listen(s, backlog) == -1) {
         anetSetError(err, "listen: %s", strerror(errno));
         close(s);
@@ -457,7 +460,7 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl
 
         if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;
         if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
-        if (anetListen(err,s,p-&gt;ai_addr,p-&gt;ai_addrlen,backlog) == ANET_ERR) s = ANET_ERR;
+        if (anetListen(err,s,p-&gt;ai_addr,p-&gt;ai_addrlen,backlog,0) == ANET_ERR) s = ANET_ERR;
         goto end;
     }
     if (p == NULL) {
@@ -498,10 +501,8 @@ int anetUnixServer(char *err, char *path, mode_t perm, int backlog)
     memset(&sa,0,sizeof(sa));
     sa.sun_family = AF_LOCAL;
     strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
-    if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog) == ANET_ERR)
+    if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog,perm) == ANET_ERR)
         return ANET_ERR;
-    if (perm)
-        chmod(sa.sun_path, perm);
     return s;
 }
 
</pre>
              </div>
            </div>
            
            <div id="applied-patches" class="tab-content">
              <h3>应用成功的补丁内容</h3>
              <div class="code-container">
                <pre class="code-block">没有应用成功的补丁块</pre>
              </div>
            </div>
            
            <div id="remaining-patch" class="tab-content">
              <h3>未应用成功的补丁内容</h3>
              <div class="code-container">
                <pre class="code-block">From 7f486ea6eebf0afce74f2e59763b9b82b78629dc Mon Sep 17 00:00:00 2001
From: Yossi Gottlieb &lt;yossigo@gmail.com&gt;
Date: Wed, 11 Oct 2023 22:45:34 +0300
Subject: [PATCH] Fix issue of listen before chmod on Unix sockets
 (CVE-2023-45145)

Before this commit, Unix socket setup performed chmod(2) on the socket
file after calling listen(2). Depending on what umask is used, this
could leave the file with the wrong permissions for a short period of
time. As a result, another process could exploit this race condition and
establish a connection that would otherwise not be possible.

We now make sure the socket permissions are set up prior to calling
listen(2).

(cherry picked from commit a11b3bc34a054818f2ac70e50adfc542ca1cba42)
---
 src/anet.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/anet.c b/src/anet.c
index 4ea201df57f..10840fca20d 100644
--- a/src/anet.c
+++ b/src/anet.c
@@ -407,13 +407,16 @@ int anetUnixGenericConnect(char *err, const char *path, int flags)
     return s;
 }
 
-static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog) {
+static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog, mode_t perm) {
     if (bind(s,sa,len) == -1) {
         anetSetError(err, "bind: %s", strerror(errno));
         close(s);
         return ANET_ERR;
     }
 
+    if (sa-&gt;sa_family == AF_LOCAL && perm)
+        chmod(((struct sockaddr_un *) sa)-&gt;sun_path, perm);
+
     if (listen(s, backlog) == -1) {
         anetSetError(err, "listen: %s", strerror(errno));
         close(s);
@@ -457,7 +460,7 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl
 
         if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;
         if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
-        if (anetListen(err,s,p-&gt;ai_addr,p-&gt;ai_addrlen,backlog) == ANET_ERR) s = ANET_ERR;
+        if (anetListen(err,s,p-&gt;ai_addr,p-&gt;ai_addrlen,backlog,0) == ANET_ERR) s = ANET_ERR;
         goto end;
     }
     if (p == NULL) {
@@ -498,10 +501,8 @@ int anetUnixServer(char *err, char *path, mode_t perm, int backlog)
     memset(&sa,0,sizeof(sa));
     sa.sun_family = AF_LOCAL;
     strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
-    if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog) == ANET_ERR)
+    if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog,perm) == ANET_ERR)
         return ANET_ERR;
-    if (perm)
-        chmod(sa.sun_path, perm);
     return s;
 }
 
</pre>
              </div>
            </div>
          </div>
        </div>
        
            <div class="card">
              <h2>剩余补丁</h2>
              <p>有 <strong class="info">3</strong> 个块未成功应用，已生成剩余补丁:</p>
              <p><code>/home/elpsy/workspace/sow/patch-backport/workspace/redis/redis/7f486e/chunk_patches/remaining_chunks_20250515_014209.patch</code></p>
              <p><a href="remaining_patch.diff" target="_blank">查看剩余补丁</a></p>
            </div>
            
        <style>
        .code-container {
          max-height: 500px;
          overflow-y: auto;
          background-color: #f8f9fa;
          border-radius: 5px;
          border: 1px solid #eee;
        }
        
        .code-block {
          padding: 15px;
          margin: 0;
          white-space: pre-wrap;
          font-family: monospace;
          font-size: 13px;
          line-height: 1.4;
        }
        
        /* 为补丁内容添加语法高亮 */
        .code-block .add {
          background-color: #e6ffed;
          color: #22863a;
        }
        
        .code-block .remove {
          background-color: #ffeef0;
          color: #cb2431;
        }
        
        .code-block .hunk {
          color: #0366d6;
          background-color: #f1f8ff;
        }
        
        .code-block .header {
          color: #6f42c1;
          font-weight: bold;
        }
        </style>
        
        <script>
        // 对补丁内容应用简单的语法高亮
        document.addEventListener('DOMContentLoaded', function() {
          const codeBlocks = document.querySelectorAll('.code-block');
          codeBlocks.forEach(function(block) {
            let html = block.innerHTML;
            
            // 替换添加的行
            html = html.replace(/^(\+[^+].*)/gm, '<span class="add">$1</span>');
            
            // 替换删除的行
            html = html.replace(/^(-[^-].*)/gm, '<span class="remove">$1</span>');
            
            // 替换区块头
            html = html.replace(/^(@@.*@@)/gm, '<span class="hunk">$1</span>');
            
            // 替换diff头 - 修复无效转义序列
            html = html.replace(/^(diff --git.*|index.*|---.*|\+\+\+.*)/gm, '<span class="header">$1</span>');
            
            block.innerHTML = html;
          });
        });
        </script>
        
    
  </div>
</body>
</html>